Micron Document
🎖️GitЯра🎖️

Node / meshtastic / Meshtastic-Android / files / core / ui / src / commonMain / kotlin / org / meshtastic / core / ui / component / SlidingSelector.kt

Displaying Raw • Download

core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/SlidingSelector.kt 520fa717a938fd84682403b41f57d9f7e1ef49ef (520fa717) Text, 15.29 KB

T8b949e/*
* Copyright (c) 2025-2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.ui.component

Tff7b72import T7ee787androidx.compose.animation.core.animateDpAsState
Tff7b72import T7ee787androidx.compose.animation.core.animateFloatAsState
Tff7b72import T7ee787androidx.compose.foundation.Canvas
Tff7b72import T7ee787androidx.compose.foundation.background
Tff7b72import T7ee787androidx.compose.foundation.gestures.awaitEachGesture
Tff7b72import T7ee787androidx.compose.foundation.gestures.awaitFirstDown
Tff7b72import T7ee787androidx.compose.foundation.gestures.horizontalDrag
Tff7b72import T7ee787androidx.compose.foundation.layout.Arrangement.spacedBy
Tff7b72import T7ee787androidx.compose.foundation.layout.Box
Tff7b72import T7ee787androidx.compose.foundation.layout.Row
Tff7b72import T7ee787androidx.compose.foundation.layout.fillMaxSize
Tff7b72import T7ee787androidx.compose.foundation.layout.fillMaxWidth
Tff7b72import T7ee787androidx.compose.foundation.layout.padding
Tff7b72import T7ee787androidx.compose.foundation.layout.wrapContentWidth
Tff7b72import T7ee787androidx.compose.foundation.selection.selectableGroup
Tff7b72import T7ee787androidx.compose.foundation.shape.RoundedCornerShape
Tff7b72import T7ee787androidx.compose.material3.LocalTextStyle
Tff7b72import T7ee787androidx.compose.material3.MaterialTheme
Tff7b72import T7ee787androidx.compose.material3.Text
Tff7b72import T7ee787androidx.compose.runtime.Composable
Tff7b72import T7ee787androidx.compose.runtime.CompositionLocalProvider
Tff7b72import T7ee787androidx.compose.runtime.getValue
Tff7b72import T7ee787androidx.compose.runtime.mutableFloatStateOf
Tff7b72import T7ee787androidx.compose.runtime.mutableIntStateOf
Tff7b72import T7ee787androidx.compose.runtime.mutableStateOf
Tff7b72import T7ee787androidx.compose.runtime.remember
Tff7b72import T7ee787androidx.compose.runtime.setValue
Tff7b72import T7ee787androidx.compose.ui.Modifier
Tff7b72import T7ee787androidx.compose.ui.composed
Tff7b72import T7ee787androidx.compose.ui.draw.alpha
Tff7b72import T7ee787androidx.compose.ui.draw.shadow
Tff7b72import T7ee787androidx.compose.ui.geometry.Offset
Tff7b72import T7ee787androidx.compose.ui.geometry.Rect
Tff7b72import T7ee787androidx.compose.ui.graphics.Color
Tff7b72import T7ee787androidx.compose.ui.graphics.TransformOrigin
Tff7b72import T7ee787androidx.compose.ui.graphics.graphicsLayer
Tff7b72import T7ee787androidx.compose.ui.input.pointer.AwaitPointerEventScope
Tff7b72import T7ee787androidx.compose.ui.input.pointer.PointerEventPass
Tff7b72import T7ee787androidx.compose.ui.input.pointer.PointerInputChange
Tff7b72import T7ee787androidx.compose.ui.input.pointer.changedToUp
Tff7b72import T7ee787androidx.compose.ui.input.pointer.pointerInput
Tff7b72import T7ee787androidx.compose.ui.layout.Layout
Tff7b72import T7ee787androidx.compose.ui.semantics.Role
Tff7b72import T7ee787androidx.compose.ui.semantics.onClick
Tff7b72import T7ee787androidx.compose.ui.semantics.role
Tff7b72import T7ee787androidx.compose.ui.semantics.selected
Tff7b72import T7ee787androidx.compose.ui.semantics.semantics
Tff7b72import T7ee787androidx.compose.ui.semantics.stateDescription
Tff7b72import T7ee787androidx.compose.ui.text.TextStyle
Tff7b72import T7ee787androidx.compose.ui.text.font.FontWeight
Tff7b72import T7ee787androidx.compose.ui.text.style.TextOverflow.Companion.Ellipsis
Tff7b72import T7ee787androidx.compose.ui.unit.Constraints
Tff7b72import T7ee787androidx.compose.ui.unit.Density
Tff7b72import T7ee787androidx.compose.ui.unit.IntOffset
Tff7b72import T7ee787androidx.compose.ui.unit.dp

Tff7b72private Tff7b72const Tff7b72val Te6edf3NO_OPTION_INDEX Tff7b72= Tff7b72-T79c0ff1

Tff7b72private Tff7b72val Te6edf3TRACK_PADDING Tff7b72= T79c0ff2.Te6edf3dp

Tff7b72private Tff7b72val Te6edf3TRACK_COLOR Tff7b72= Te6edf3ColorTb4b4b4.Te6edf3LightGrayTb4b4b4.Te6edf3copyTb4b4b4(Te6edf3alpha Tff7b72= Tb4b4b4.T79c0ff5fTb4b4b4)

Tff7b72private Tff7b72val Te6edf3PRESSED_TRACK_PADDING Tff7b72= T79c0ff1.Te6edf3dp

Tff7b72private Tff7b72val Te6edf3OPTION_PADDING Tff7b72= T79c0ff5.Te6edf3dp

Tff7b72private Tff7b72const Tff7b72val Te6edf3PRESSED_UNSELECTED_ALPHA Tff7b72= Tb4b4b4.T79c0ff6f

Tff7b72private Tff7b72val Te6edf3BACKGROUND_SHAPE Tff7b72= Te6edf3RoundedCornerShapeTb4b4b4(T79c0ff8.Te6edf3dpTb4b4b4)

T8b949e/**
* Provides the user with a set of options they can choose from.
*
* (Inspired by https://gist.github.com/zach-klippenstein/7ae8874db304f957d6bb91263e292117)
*/
Tf0883e@Composable
Tff7b72fun Tff7b72<Te6edf3T Tb4b4b4: Te6edf3AnyTff7b72> Td2a8ffSlidingSelectorTb4b4b4(
Te6edf3optionsTb4b4b4: Te6edf3ListTff7b72<Te6edf3TTff7b72>Tb4b4b4,
Te6edf3selectedOptionTb4b4b4: Te6edf3TTb4b4b4,
Te6edf3onOptionSelectedTb4b4b4: Tb4b4b4(Te6edf3TTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4,
Te6edf3modifierTb4b4b4: Te6edf3Modifier Tff7b72= Te6edf3ModifierTb4b4b4,
Te6edf3contentTb4b4b4: Tf0883e@Composable Tb4b4b4(Te6edf3TTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3state Tff7b72= Te6edf3remember Tb4b4b4{ Te6edf3SelectorStateTb4b4b4(Tb4b4b4) Tb4b4b4}
Te6edf3stateTb4b4b4.Te6edf3optionCount Tff7b72= Te6edf3optionsTb4b4b4.Te6edf3size
Te6edf3stateTb4b4b4.Te6edf3selectedOption Tff7b72= Te6edf3optionsTb4b4b4.Te6edf3indexOfTb4b4b4(Te6edf3selectedOptionTb4b4b4)
Te6edf3stateTb4b4b4.Te6edf3onOptionSelected Tff7b72= Tb4b4b4{ Te6edf3onOptionSelectedTb4b4b4(Te6edf3optionsTff7b72[Tffa657itTff7b72]Tb4b4b4) Tb4b4b4}

T8b949e/* Animate between whole-number indices so we don't need to do pixel calculations. */
Tff7b72val Te6edf3selectedIndexOffset Tff7b72by Te6edf3animateFloatAsStateTb4b4b4(Te6edf3stateTb4b4b4.Te6edf3selectedOptionTb4b4b4.Te6edf3toFloatTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3label Tff7b72= Ta5d6ff"Ta5d6ffSelected Index OffsetTa5d6ff"Tb4b4b4)

Te6edf3LayoutTb4b4b4(
Te6edf3content Tff7b72= Tb4b4b4{
Te6edf3SelectedIndicatorTb4b4b4(Te6edf3stateTb4b4b4)
Te6edf3DividersTb4b4b4(Te6edf3stateTb4b4b4)
Te6edf3OptionsTb4b4b4(Te6edf3stateTb4b4b4, Te6edf3optionsTb4b4b4, Te6edf3contentTb4b4b4)
Tb4b4b4}Tb4b4b4,
Te6edf3modifier Tff7b72=
Te6edf3modifier
Tb4b4b4.Te6edf3fillMaxWidthTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3thenTb4b4b4(Te6edf3stateTb4b4b4.Te6edf3inputModifierTb4b4b4)
Tb4b4b4.Te6edf3backgroundTb4b4b4(Te6edf3TRACK_COLORTb4b4b4, Te6edf3BACKGROUND_SHAPETb4b4b4)
Tb4b4b4.Te6edf3paddingTb4b4b4(Te6edf3TRACK_PADDINGTb4b4b4)Tb4b4b4,
Tb4b4b4) Tb4b4b4{ Te6edf3measurablesTb4b4b4, Te6edf3constraints Tff7b72-Tff7b72>
Tff7b72val Tb4b4b4(Te6edf3indicatorMeasurableTb4b4b4, Te6edf3dividersMeasurableTb4b4b4, Te6edf3optionsMeasurableTb4b4b4) Tff7b72= Te6edf3measurables

T8b949e/* Measure the options first so we know how tall to make the indicator. */
Tff7b72val Te6edf3optionsPlaceable Tff7b72= Te6edf3optionsMeasurableTb4b4b4.Te6edf3measureTb4b4b4(Te6edf3constraintsTb4b4b4)
Te6edf3stateTb4b4b4.Te6edf3updatePressedScaleTb4b4b4(Te6edf3optionsPlaceableTb4b4b4.Te6edf3heightTb4b4b4, Tff7b72thisTb4b4b4)

T8b949e/* Measure the indicator and dividers to be the right size. */
Tff7b72val Te6edf3indicatorPlaceable Tff7b72=
Te6edf3indicatorMeasurableTb4b4b4.Te6edf3measureTb4b4b4(
Te6edf3ConstraintsTb4b4b4.Te6edf3fixedTb4b4b4(Te6edf3width Tff7b72= Te6edf3optionsPlaceableTb4b4b4.Te6edf3width Tff7b72/ Te6edf3optionsTb4b4b4.Te6edf3sizeTb4b4b4, Te6edf3height Tff7b72= Te6edf3optionsPlaceableTb4b4b4.Te6edf3heightTb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72val Te6edf3dividersPlaceable Tff7b72=
Te6edf3dividersMeasurableTb4b4b4.Te6edf3measureTb4b4b4(
Te6edf3ConstraintsTb4b4b4.Te6edf3fixedTb4b4b4(Te6edf3width Tff7b72= Te6edf3optionsPlaceableTb4b4b4.Te6edf3widthTb4b4b4, Te6edf3height Tff7b72= Te6edf3optionsPlaceableTb4b4b4.Te6edf3heightTb4b4b4)Tb4b4b4,
Tb4b4b4)

Te6edf3layoutTb4b4b4(Te6edf3optionsPlaceableTb4b4b4.Te6edf3widthTb4b4b4, Te6edf3optionsPlaceableTb4b4b4.Te6edf3heightTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3optionWidth Tff7b72= Te6edf3optionsPlaceableTb4b4b4.Te6edf3width Tff7b72/ Te6edf3optionsTb4b4b4.Te6edf3size

T8b949e/* Place the indicator first so that it's below the option labels. */
Te6edf3indicatorPlaceableTb4b4b4.Te6edf3placeRelativeTb4b4b4(Te6edf3x Tff7b72= Tb4b4b4(Te6edf3selectedIndexOffset Tff7b72* Te6edf3optionWidthTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3y Tff7b72= T79c0ff0Tb4b4b4)
Te6edf3dividersPlaceableTb4b4b4.Te6edf3placeRelativeTb4b4b4(Te6edf3IntOffsetTb4b4b4.Te6edf3ZeroTb4b4b4)
Te6edf3optionsPlaceableTb4b4b4.Te6edf3placeRelativeTb4b4b4(Te6edf3IntOffsetTb4b4b4.Te6edf3ZeroTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

T8b949e/** Visual representation of the option the user may select. */
Tf0883e@Composable
Tff7b72fun Td2a8ffOptionLabelTb4b4b4(Te6edf3textTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Te6edf3TextTb4b4b4(Te6edf3textTb4b4b4, Te6edf3maxLines Tff7b72= T79c0ff1Tb4b4b4, Te6edf3overflow Tff7b72= Te6edf3EllipsisTb4b4b4)
Tb4b4b4}

T8b949e/** Draws the selected indicator on the [SlidingSelector] track. */
Tf0883e@Composable
Tff7b72private Tff7b72fun Td2a8ffSelectedIndicatorTb4b4b4(Te6edf3stateTb4b4b4: Te6edf3SelectorStateTb4b4b4) Tb4b4b4{
Te6edf3BoxTb4b4b4(
Te6edf3ModifierTb4b4b4.Te6edf3thenTb4b4b4(
Te6edf3stateTb4b4b4.Te6edf3optionScaleModifierTb4b4b4(
Te6edf3pressed Tff7b72= Te6edf3stateTb4b4b4.Te6edf3pressedOption Tff7b72=Tff7b72= Te6edf3stateTb4b4b4.Te6edf3selectedOptionTb4b4b4,
Te6edf3option Tff7b72= Te6edf3stateTb4b4b4.Te6edf3selectedOptionTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4.Te6edf3shadowTb4b4b4(T79c0ff4.Te6edf3dpTb4b4b4, Te6edf3BACKGROUND_SHAPETb4b4b4)
Tb4b4b4.Te6edf3backgroundTb4b4b4(Te6edf3MaterialThemeTb4b4b4.Te6edf3colorSchemeTb4b4b4.Te6edf3backgroundTb4b4b4, Te6edf3BACKGROUND_SHAPETb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}

T8b949e/** Draws dividers between [OptionLabel]s. */
Tf0883e@Composable
Tff7b72private Tff7b72fun Td2a8ffDividersTb4b4b4(Te6edf3stateTb4b4b4: Te6edf3SelectorStateTb4b4b4) Tb4b4b4{
T8b949e/* Animate each divider independently. */
Tff7b72val Te6edf3alphas Tff7b72=
Tb4b4b4(T79c0ff0 Te6edf3until Te6edf3stateTb4b4b4.Te6edf3optionCountTb4b4b4)Tb4b4b4.Te6edf3map Tb4b4b4{ Te6edf3i Tff7b72-Tff7b72>
Tff7b72val Te6edf3selectionAdjacent Tff7b72= Te6edf3i Tff7b72=Tff7b72= Te6edf3stateTb4b4b4.Te6edf3selectedOption Tff7b72|Tff7b72| Te6edf3i Tff7b72- T79c0ff1 Tff7b72=Tff7b72= Te6edf3stateTb4b4b4.Te6edf3selectedOption
Te6edf3animateFloatAsStateTb4b4b4(Tff7b72if Tb4b4b4(Te6edf3selectionAdjacentTb4b4b4) T79c0ff0f Tff7b72else T79c0ff1fTb4b4b4, Te6edf3label Tff7b72= Ta5d6ff"Ta5d6ffDividersTa5d6ff"Tb4b4b4)
Tb4b4b4}

Te6edf3CanvasTb4b4b4(Te6edf3ModifierTb4b4b4.Te6edf3fillMaxSizeTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3optionWidth Tff7b72= Te6edf3sizeTb4b4b4.Te6edf3width Tff7b72/ Te6edf3stateTb4b4b4.Te6edf3optionCount
Tff7b72val Te6edf3dividerPadding Tff7b72= Te6edf3TRACK_PADDING Tff7b72+ Te6edf3PRESSED_TRACK_PADDING

Te6edf3alphasTb4b4b4.Te6edf3forEachIndexed Tb4b4b4{ Te6edf3iTb4b4b4, Te6edf3alpha Tff7b72-Tff7b72>
Tff7b72val Te6edf3x Tff7b72= Te6edf3i Tff7b72* Te6edf3optionWidth
Te6edf3drawLineTb4b4b4(
Te6edf3ColorTb4b4b4.Te6edf3WhiteTb4b4b4,
Te6edf3alpha Tff7b72= Te6edf3alphaTb4b4b4.Te6edf3valueTb4b4b4,
Te6edf3start Tff7b72= Te6edf3OffsetTb4b4b4(Te6edf3xTb4b4b4, Te6edf3dividerPaddingTb4b4b4.Te6edf3toPxTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3end Tff7b72= Te6edf3OffsetTb4b4b4(Te6edf3xTb4b4b4, Te6edf3sizeTb4b4b4.Te6edf3height Tff7b72- Te6edf3dividerPaddingTb4b4b4.Te6edf3toPxTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

T8b949e/** Draws the options available to the user. */
Tf0883e@Composable
Tff7b72private Tff7b72fun Tff7b72<Te6edf3TTff7b72> Td2a8ffOptionsTb4b4b4(Te6edf3stateTb4b4b4: Te6edf3SelectorStateTb4b4b4, Te6edf3optionsTb4b4b4: Te6edf3ListTff7b72<Te6edf3TTff7b72>Tb4b4b4, Te6edf3contentTb4b4b4: Tf0883e@Composable Tb4b4b4(Te6edf3TTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4) Tb4b4b4{
Te6edf3CompositionLocalProviderTb4b4b4(Te6edf3LocalTextStyle Te6edf3provides Te6edf3TextStyleTb4b4b4(Te6edf3fontWeight Tff7b72= Te6edf3FontWeightTb4b4b4.Te6edf3MediumTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3RowTb4b4b4(Te6edf3horizontalArrangement Tff7b72= Te6edf3spacedByTb4b4b4(Te6edf3TRACK_PADDINGTb4b4b4)Tb4b4b4, Te6edf3modifier Tff7b72= Te6edf3ModifierTb4b4b4.Te6edf3fillMaxWidthTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3selectableGroupTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3optionsTb4b4b4.Te6edf3forEachIndexed Tb4b4b4{ Te6edf3iTb4b4b4, Te6edf3timeFrame Tff7b72-Tff7b72>
Tff7b72val Te6edf3isSelected Tff7b72= Te6edf3i Tff7b72=Tff7b72= Te6edf3stateTb4b4b4.Te6edf3selectedOption
Tff7b72val Te6edf3isPressed Tff7b72= Te6edf3i Tff7b72=Tff7b72= Te6edf3stateTb4b4b4.Te6edf3pressedOption

T8b949e/* Unselected presses are represented by fading. */
Tff7b72val Te6edf3alpha Tff7b72by
Te6edf3animateFloatAsStateTb4b4b4(
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3isSelected Tff7b72&Tff7b72& Te6edf3isPressedTb4b4b4) Te6edf3PRESSED_UNSELECTED_ALPHA Tff7b72else T79c0ff1fTb4b4b4,
Te6edf3label Tff7b72= Ta5d6ff"Ta5d6ffUnselectedTa5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72val Te6edf3semanticsModifier Tff7b72=
Te6edf3ModifierTb4b4b4.Te6edf3semanticsTb4b4b4(Te6edf3mergeDescendants Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{
Te6edf3selected Tff7b72= Te6edf3isSelected
Te6edf3role Tff7b72= Te6edf3RoleTb4b4b4.Te6edf3Button
Te6edf3onClick Tb4b4b4{
Te6edf3stateTb4b4b4.Te6edf3onOptionSelectedTb4b4b4(Te6edf3iTb4b4b4)
Tff7b72true
Tb4b4b4}
Te6edf3stateDescription Tff7b72= Tff7b72if Tb4b4b4(Te6edf3isSelectedTb4b4b4) Ta5d6ff"Ta5d6ffSelectedTa5d6ff" Tff7b72else Ta5d6ff"Ta5d6ffNot selectedTa5d6ff"
Tb4b4b4}

Te6edf3BoxTb4b4b4(
Te6edf3Modifier
T8b949e/* Divide space evenly between all options. */
Tb4b4b4.Te6edf3weightTb4b4b4(T79c0ff1fTb4b4b4)
Tb4b4b4.Te6edf3thenTb4b4b4(Te6edf3semanticsModifierTb4b4b4)
Tb4b4b4.Te6edf3paddingTb4b4b4(Te6edf3OPTION_PADDINGTb4b4b4)
T8b949e/* Draw pressed indication when not selected. */
Tb4b4b4.Te6edf3alphaTb4b4b4(Te6edf3alphaTb4b4b4)
T8b949e/* Selected presses are represented by scaling. */
Tb4b4b4.Te6edf3thenTb4b4b4(Te6edf3stateTb4b4b4.Te6edf3optionScaleModifierTb4b4b4(Te6edf3isPressed Tff7b72&Tff7b72& Te6edf3isSelectedTb4b4b4, Te6edf3iTb4b4b4)Tb4b4b4)
T8b949e/* Center the option content. */
Tb4b4b4.Te6edf3wrapContentWidthTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3contentTb4b4b4(Te6edf3timeFrameTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

T8b949e/** Contains and handles the state necessary to present the [SlidingSelector] to the user. */
Tff7b72private Tff7b72class T56d364SelectorState Tb4b4b4{
Tff7b72var Te6edf3optionCount Tff7b72by Te6edf3mutableIntStateOfTb4b4b4(T79c0ff0Tb4b4b4)
Tff7b72var Te6edf3selectedOption Tff7b72by Te6edf3mutableIntStateOfTb4b4b4(T79c0ff0Tb4b4b4)
Tff7b72var Te6edf3onOptionSelectedTb4b4b4: Tb4b4b4(Tffa657IntTb4b4b4) Tff7b72-Tff7b72> Tffa657Unit Tff7b72by Te6edf3mutableStateOfTb4b4b4(Tb4b4b4{Tb4b4b4}Tb4b4b4)
Tff7b72var Te6edf3pressedOption Tff7b72by Te6edf3mutableIntStateOfTb4b4b4(Te6edf3NO_OPTION_INDEXTb4b4b4)

T8b949e/**
* Scale factor that should be used to scale pressed option. When this scale is applied, exactly
* [PRESSED_TRACK_PADDING] will be added around the element's usual size.
*/
Tff7b72var Te6edf3pressedSelectedScale Tff7b72by Te6edf3mutableFloatStateOfTb4b4b4(T79c0ff1fTb4b4b4)
Te6edf3private Tff7b72set

T8b949e/** Calculates the scale factor we need to use for pressed options to get the desired padding. */
Tff7b72fun Td2a8ffupdatePressedScaleTb4b4b4(Te6edf3controlHeightTb4b4b4: Tffa657IntTb4b4b4, Te6edf3densityTb4b4b4: Te6edf3DensityTb4b4b4) Tb4b4b4{
Te6edf3withTb4b4b4(Te6edf3densityTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3pressedPadding Tff7b72= Te6edf3PRESSED_TRACK_PADDING Tff7b72* T79c0ff2
Tff7b72val Te6edf3pressedHeight Tff7b72= Te6edf3controlHeight Tff7b72- Te6edf3pressedPaddingTb4b4b4.Te6edf3toPxTb4b4b4(Tb4b4b4)
Te6edf3pressedSelectedScale Tff7b72= Te6edf3pressedHeight Tff7b72/ Te6edf3controlHeight
Tb4b4b4}
Tb4b4b4}

T8b949e/**
* Returns a [Modifier] that will scale an element so that it gets [PRESSED_TRACK_PADDING] extra padding around it.
* The scale will be animated.
*
* The scale is also performed around either the left or right edge of the element if the option is the first or
* last option, respectively. In those cases, the scale will also be translated so that [PRESSED_TRACK_PADDING] will
* be added on the left or right edge.
*/
Tff7b72fun Td2a8ffoptionScaleModifierTb4b4b4(Te6edf3pressedTb4b4b4: Tffa657BooleanTb4b4b4, Te6edf3optionTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Te6edf3Modifier Tff7b72= Te6edf3ModifierTb4b4b4.Te6edf3composed Tb4b4b4{
Tff7b72val Te6edf3scale Tff7b72by Te6edf3animateFloatAsStateTb4b4b4(Tff7b72if Tb4b4b4(Te6edf3pressedTb4b4b4) Te6edf3pressedSelectedScale Tff7b72else T79c0ff1fTb4b4b4, Te6edf3label Tff7b72= Ta5d6ff"Ta5d6ffScaleTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3xOffset Tff7b72by Te6edf3animateDpAsStateTb4b4b4(Tff7b72if Tb4b4b4(Te6edf3pressedTb4b4b4) Te6edf3PRESSED_TRACK_PADDING Tff7b72else T79c0ff0.Te6edf3dpTb4b4b4, Te6edf3label Tff7b72= Ta5d6ff"Ta5d6ffx OffsetTa5d6ff"Tb4b4b4)

Te6edf3graphicsLayer Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3scaleX Tff7b72= Te6edf3scale
Tff7b72thisTb4b4b4.Te6edf3scaleY Tff7b72= Te6edf3scale

T8b949e/* Scales on the ends should gravitate to that edge. */
Tff7b72thisTb4b4b4.Te6edf3transformOrigin Tff7b72=
Te6edf3TransformOriginTb4b4b4(
Te6edf3pivotFractionX Tff7b72=
Tff7b72when Tb4b4b4(Te6edf3optionTb4b4b4) Tb4b4b4{
T79c0ff0 Tff7b72-Tff7b72> T79c0ff0f
Te6edf3optionCount Tff7b72- T79c0ff1 Tff7b72-Tff7b72> T79c0ff1f
Tff7b72else Tff7b72-Tff7b72> Tb4b4b4.T79c0ff5f
Tb4b4b4}Tb4b4b4,
Te6edf3pivotFractionY Tff7b72= Tb4b4b4.T79c0ff5fTb4b4b4,
Tb4b4b4)

T8b949e/* But should still move inwards to keep the pressed padding consistent with top and bottom. */
Tff7b72thisTb4b4b4.Te6edf3translationX Tff7b72=
Tff7b72when Tb4b4b4(Te6edf3optionTb4b4b4) Tb4b4b4{
T79c0ff0 Tff7b72-Tff7b72> Te6edf3xOffsetTb4b4b4.Te6edf3toPxTb4b4b4(Tb4b4b4)
Te6edf3optionCount Tff7b72- T79c0ff1 Tff7b72-Tff7b72> Tff7b72-Te6edf3xOffsetTb4b4b4.Te6edf3toPxTb4b4b4(Tb4b4b4)
Tff7b72else Tff7b72-Tff7b72> T79c0ff0f
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

T8b949e/**
* A [Modifier] that will listen for touch gestures and update the selected and pressed properties of this state
* appropriately.
*/
Tff7b72val Te6edf3inputModifier Tff7b72=
Te6edf3ModifierTb4b4b4.Te6edf3pointerInputTb4b4b4(Te6edf3optionCountTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3optionWidth Tff7b72= Te6edf3sizeTb4b4b4.Te6edf3width Tff7b72/ Te6edf3optionCount

T8b949e/* Helper to calculate which option an event occurred in. */
Tff7b72fun Td2a8ffoptionIndexTb4b4b4(Te6edf3changeTb4b4b4: Te6edf3PointerInputChangeTb4b4b4)Tb4b4b4: Tffa657Int Tff7b72=
Tb4b4b4(Tb4b4b4(Te6edf3changeTb4b4b4.Te6edf3positionTb4b4b4.Te6edf3x Tff7b72/ Te6edf3sizeTb4b4b4.Te6edf3widthTb4b4b4.Te6edf3toFloatTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72* Te6edf3optionCountTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3coerceInTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3optionCount Tff7b72- T79c0ff1Tb4b4b4)

Te6edf3awaitEachGesture Tb4b4b4{
Tff7b72val Te6edf3down Tff7b72= Te6edf3awaitFirstDownTb4b4b4(Tb4b4b4)

Te6edf3pressedOption Tff7b72= Te6edf3optionIndexTb4b4b4(Te6edf3downTb4b4b4)
Tff7b72val Te6edf3downOnSelected Tff7b72= Te6edf3pressedOption Tff7b72=Tff7b72= Te6edf3selectedOption
Tff7b72val Te6edf3optionBounds Tff7b72=
Te6edf3RectTb4b4b4(
Te6edf3left Tff7b72= Te6edf3pressedOption Tff7b72* Te6edf3optionWidthTb4b4b4.Te6edf3toFloatTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3right Tff7b72= Tb4b4b4(Te6edf3pressedOption Tff7b72+ T79c0ff1Tb4b4b4) Tff7b72* Te6edf3optionWidthTb4b4b4.Te6edf3toFloatTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3top Tff7b72= T79c0ff0fTb4b4b4,
Te6edf3bottom Tff7b72= Te6edf3sizeTb4b4b4.Te6edf3heightTb4b4b4.Te6edf3toFloatTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3downOnSelectedTb4b4b4) Tb4b4b4{
Te6edf3horizontalDragTb4b4b4(Te6edf3downTb4b4b4.Te6edf3idTb4b4b4) Tb4b4b4{ Te6edf3change Tff7b72-Tff7b72>
Te6edf3pressedOption Tff7b72= Te6edf3optionIndexTb4b4b4(Te6edf3changeTb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3pressedOption Tff7b72!Tff7b72= Te6edf3selectedOptionTb4b4b4) Tb4b4b4{
Te6edf3onOptionSelectedTb4b4b4(Te6edf3pressedOptionTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3waitForUpOrCancellationTb4b4b4(Te6edf3inBounds Tff7b72= Te6edf3optionBoundsTb4b4b4)
T8b949e/* Null means the gesture was cancelled (e.g. dragged out of bounds). */
Tff7b72?.Te6edf3let Tb4b4b4{ Te6edf3onOptionSelectedTb4b4b4(Te6edf3pressedOptionTb4b4b4) Tb4b4b4}
Tb4b4b4}
Te6edf3pressedOption Tff7b72= Te6edf3NO_OPTION_INDEX
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

T8b949e/** Works with bounds that may not be at 0,0. */
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffReturnCountTa5d6ff"Tb4b4b4)
Tff7b72private Tff7b72suspend Tff7b72fun Te6edf3AwaitPointerEventScopeTb4b4b4.Td2a8ffwaitForUpOrCancellationTb4b4b4(Te6edf3inBoundsTb4b4b4: Te6edf3RectTb4b4b4)Tb4b4b4: Te6edf3PointerInputChange? Tb4b4b4{
Tff7b72while Tb4b4b4(Tff7b72trueTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3event Tff7b72= Te6edf3awaitPointerEventTb4b4b4(Te6edf3PointerEventPassTb4b4b4.Te6edf3MainTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3eventTb4b4b4.Te6edf3changesTb4b4b4.Te6edf3all Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3changedToUpTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4) Tb4b4b4{
T8b949e/* All pointers are up */
Tff7b72return Te6edf3eventTb4b4b4.Te6edf3changesTff7b72[T79c0ff0Tff7b72]
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3eventTb4b4b4.Te6edf3changesTb4b4b4.Te6edf3any Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isConsumed Tff7b72|Tff7b72| Tff7b72!Te6edf3inBoundsTb4b4b4.Te6edf3containsTb4b4b4(Tffa657itTb4b4b4.Te6edf3positionTb4b4b4) Tb4b4b4}Tb4b4b4) Tb4b4b4{
T8b949e/* Canceled */
Tff7b72return Tff7b72null
Tb4b4b4}

Tff7b72val Te6edf3consumeCheck Tff7b72= Te6edf3awaitPointerEventTb4b4b4(Te6edf3PointerEventPassTb4b4b4.Te6edf3FinalTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3consumeCheckTb4b4b4.Te6edf3changesTb4b4b4.Te6edf3any Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isConsumed Tb4b4b4}Tb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

T8b949e/*@Preview
@Composable
fun SlidingSelectorPreview() {
MaterialTheme {
Surface {
Column(Modifier.padding(8.dp)) {

var selectedOption by remember { mutableStateOf(TimeFrame.TWENTY_FOUR_HOURS) }
SlidingSelector(
TimeFrame.entries.toList(),
selectedOption,
onOptionSelected = { selectedOption = it }
) {
OptionLabel(stringResource(it.strRes))
}
}
}
}
}*/

Served by rngit 1.5.0 - Generated in 0.12s